<template>
  <div class="bg-gray-50 font-inter text-dark min-h-screen flex flex-col">
    <!-- 顶部导航栏 -->
    <header class="bg-white shadow-md sticky top-0 z-50 transition-all duration-300">
      <div class="container mx-auto px-4 py-4 flex justify-between items-center">
        <div class="flex items-center space-x-2">
          <FontAwesomeIcon icon="bar-chart" class="text-primary text-2xl" />
          <h1 class="text-xl md:text-2xl font-bold text-dark" title="主要用于  解析JavaScript 的 VMP防护的加密算法， 可以通过图标查看到加密算法整体流程（因市面上大多网站的 jsvmp 防护是基于栈去设计， 不断的压栈出栈）">文本字数波浪线图分析工具</h1>
        </div>
        <nav>
          <ul class="flex space-x-6">
            <li>
              <a href="/" class="text-gray-600 hover:text-primary transition-custom flex items-center">
                <FontAwesomeIcon icon="home" class="mr-1" />
                首页
              </a>
            </li>
            <li>
              <a href="/help" class="text-gray-600 hover:text-primary transition-custom flex items-center">
                <FontAwesomeIcon icon="question-circle" class="mr-1" />
                帮助
              </a>
            </li>
          </ul>
        </nav>
      </div>
    </header>

    <!-- 主内容区 -->
    <main class="flex-grow container mx-auto px-4 py-8">
      <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
        <!-- 左侧面板 -->
        <div class="lg:col-span-1 space-y-6">
          <!-- 文件上传 -->
          <div class="bg-white rounded-xl shadow-lg p-6 transform hover:shadow-xl transition-custom">
            <h2 class="text-lg font-semibold mb-4 flex items-center">
              <FontAwesomeIcon icon="file-text" class="text-primary mr-2" />
              文件上传
            </h2>
            <div 
              class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-primary transition-custom cursor-pointer"
              @dragover="handleDragOver"
              @dragleave="handleDragLeave"
              @drop="handleDrop"
              ref="fileDropArea"
            >
              <FontAwesomeIcon icon="cloud-upload" class="text-4xl text-gray-400 mb-4" />
              <p class="text-gray-500 mb-2">拖放文件到此处或</p>
              <button 
                class="bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-lg transition-custom"
                @click="handleFileClick"
              >
                <FontAwesomeIcon icon="folder-open" class="mr-1" />
                选择文件
              </button>
              <input 
                type="file" 
                ref="fileInput" 
                class="hidden" 
                accept=".txt,.js"
                @change="handleFileChange"
              >
              <p class="text-xs text-gray-400 mt-4">支持 .txt 和 .js 文件</p>
            </div>
          </div>

          <!-- 文本输入 -->
          <div class="bg-white rounded-xl shadow-lg p-6 transform hover:shadow-xl transition-custom">
            <h2 class="text-lg font-semibold mb-4 flex items-center">
              <FontAwesomeIcon icon="pencil-square" class="text-primary mr-2" />
              文本输入
            </h2>
            <div class="mb-4">
              <textarea 
                v-model="textInput"
                rows="10"
                class="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary focus:border-primary transition-custom"
                placeholder="或者直接粘贴文本内容..."
              ></textarea>
            </div>
            <div class="flex space-x-3">
              <button 
                class="flex-1 bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-lg transition-custom flex items-center justify-center"
                @click="analyzeText"
              >
                <FontAwesomeIcon icon="line-chart" class="mr-2" />
                分析文本
              </button>
              <button 
                class="bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded-lg transition-custom"
                @click="generateRandomText"
              >
                <FontAwesomeIcon icon="random" />
              </button>
            </div>
          </div>

          <!-- 图表设置 -->
          <div class="bg-white rounded-xl shadow-lg p-6 transform hover:shadow-xl transition-custom">
            <h2 class="text-lg font-semibold mb-4 flex items-center">
              <FontAwesomeIcon icon="sliders" class="text-primary mr-2" />
              图表设置
            </h2>
            <div class="space-y-4">
              <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">波浪动画</label>
                <div class="flex items-center space-x-4">
                  <label class="inline-flex items-center">
                    <input 
                      type="radio" 
                      name="animation" 
                      value="smooth" 
                      class="form-radio text-primary"
                      checked
                      v-model="animationType"
                    >
                    <span class="ml-2">平滑</span>
                  </label>
                  <label class="inline-flex items-center">
                    <input 
                      type="radio" 
                      name="animation" 
                      value="wave" 
                      class="form-radio text-primary"
                      v-model="animationType"
                    >
                    <span class="ml-2">波浪</span>
                  </label>
                  <label class="inline-flex items-center">
                    <input 
                      type="radio" 
                      name="animation" 
                      value="none" 
                      class="form-radio text-primary"
                      v-model="animationType"
                    >
                    <span class="ml-2">无</span>
                  </label>
                </div>
              </div>

              <div>
                <label class="block text-sm font-medium text-gray-700 mb-1">图表颜色</label>
                <div class="grid grid-cols-4 gap-2">
                  <button 
                    v-for="(color, index) in chartColors"
                    :key="index"
                    class="color-option h-8 rounded-full transition-custom"
                    :style="{ backgroundColor: color.value }"
                    @click="handleColorClick(color)"
                    :class="{ 'border-2 border-gray-500': chartColor === color.name }"
                  ></button>
                </div>
              </div>

              <div>
                <label for="pointSize" class="block text-sm font-medium text-gray-700 mb-1">点大小</label>
                <input 
                  type="range" 
                  id="pointSize" 
                  min="2" 
                  max="10" 
                  :value="pointSize"
                  @input="handlePointSizeChange"
                  class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary"
                >
              </div>

              <div>
                <label for="lineWidth" class="block text-sm font-medium text-gray-700 mb-1">线宽</label>
                <input 
                  type="range" 
                  id="lineWidth" 
                  min="1" 
                  max="5" 
                  :value="lineWidth"
                  @input="handleLineWidthChange"
                  class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-primary"
                >
              </div>
            </div>
          </div>
        </div>

        <!-- 右侧面板 -->
        <div class="lg:col-span-2 space-y-6">
          <!-- 分析结果 -->
          <div class="bg-white rounded-xl shadow-lg p-6 transform hover:shadow-xl transition-custom">
            <h2 class="text-lg font-semibold mb-4 flex items-center">
              <FontAwesomeIcon icon="table" class="text-primary mr-2" />
              分析结果
            </h2>
            <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-4">
              <div class="bg-blue-50 rounded-lg p-4 border-l-4 border-primary">
                <p class="text-sm text-gray-500">总行数</p>
                <p class="text-2xl font-bold text-primary">{{ totalLines }}</p>
              </div>
              <div class="bg-green-50 rounded-lg p-4 border-l-4 border-green-500">
                <p class="text-sm text-gray-500">平均字数</p>
                <p class="text-2xl font-bold text-green-500">{{ avgChars }}</p>
              </div>
              <div class="bg-purple-50 rounded-lg p-4 border-l-4 border-purple-500">
                <p class="text-sm text-gray-500">最多字数</p>
                <p class="text-2xl font-bold text-purple-500">{{ maxChars }}</p>
              </div>
              <div class="bg-red-50 rounded-lg p-4 border-l-4 border-red-500">
                <p class="text-sm text-gray-500">最少字数</p>
                <p class="text-2xl font-bold text-red-500">{{ minChars }}</p>
              </div>
            </div>

            <div class="overflow-x-auto max-h-[400px] overflow-y-auto">
              <table class="min-w-full divide-y divide-gray-200">
                <!-- <thead class="bg-gray-50">
                  <tr>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">行号</th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">字数</th>
                    <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">内容预览</th>
                  </tr>
                </thead> -->
                <tbody>
                  <tr 
                    v-for="(line, index) in lines"
                    :key="index"
                    :class="index % 2 === 0 ? 'bg-white' : 'bg-gray-50'"
                  >
                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">{{ index + 1 }}</td>
                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{{ wordCounts[index] }}</td>
                    <td class="px-6 py-4 text-sm text-gray-500">
                      {{ line.length > 50 ? line.slice(0, 50) + '...' : line }}
                    </td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>

          <!-- 波浪线图 -->
          <div class="bg-white rounded-xl shadow-lg p-6 transform hover:shadow-xl transition-custom">
            <h2 class="text-lg font-semibold mb-4 flex items-center justify-between">
  <div class="flex items-center">
    <FontAwesomeIcon icon="area-chart" class="text-primary mr-2" />
    字数波浪线图
  </div>
  <div class="flex space-x-2">
    <button 
      class="bg-primary hover:bg-primary/90 text-white py-1 px-3 rounded-lg transition-custom flex items-center"
      @click="handleZoomOut"
    >
      <FontAwesomeIcon icon="minus" class="mr-1" />
      缩小
    </button>
    <button 
      class="bg-primary hover:bg-primary/90 text-white py-1 px-3 rounded-lg transition-custom flex items-center"
      @click="handleZoomIn"
    >
      <FontAwesomeIcon icon="plus" class="mr-1" />
      放大
    </button>
  </div>
</h2>
            <div class="relative h-80 flex">
              <canvas ref="waveChart" width="1200" height="400"></canvas>
              <div v-show="selectedPoint" class="ml-4 p-4 bg-gray-100 rounded-lg shadow-sm min-w-[150px]">
                <p class="text-sm text-gray-600">行号：{{ selectedPoint?.lineNumber }}</p>
                <p class="text-sm text-gray-800">内容：{{ selectedPoint?.content }}</p>
              </div>
            </div>
            <!-- 修改为始终显示的内容区域 -->
            <div class="mt-4 p-4 bg-gray-50 rounded-lg border border-gray-200">
              <h3 class="font-medium mb-2">选中行内容：</h3>
              <p class="whitespace-pre-wrap">{{ selectedPoint?.content || '请点击图表上的点查看对应行内容' }}</p>
            </div>
          </div>
        </div>
      </div>
    </main>

    <!-- 页脚 -->
    <footer class="bg-dark text-white py-6 mt-8">
      <div class="container mx-auto px-4">
        <div class="flex flex-col md:flex-row justify-between items-center">
          <div class="mb-4 md:mb-0">
            <p class="text-sm text-gray-400">
              &copy; 2025 文本分析工具 | 版权所有
            </p>
          </div>
        </div>
      </div>
    </footer>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, onBeforeUnmount } from 'vue';
import Chart from 'chart.js/auto';
import zoomPlugin from 'chartjs-plugin-zoom';
Chart.register(zoomPlugin);
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import { library } from '@fortawesome/fontawesome-svg-core';
import { 
  faBarChart, 
  faHome, 
  faQuestionCircle, 
  faFileText, 
  faCloudUpload, 
  faFolderOpen, 
  faPencilSquare, 
  faLineChart, 
  faRandom, 
  faSliders, 
  faCheckCircle, 
  faExclamationCircle, 
  faExclamationTriangle, 
  faInfoCircle, 
  faPlus, 
  faMinus 
} from '@fortawesome/free-solid-svg-icons';

// 初始化FontAwesome图标库
library.add(
  faBarChart, 
  faHome, 
  faQuestionCircle, 
  faFileText, 
  faCloudUpload, 
  faFolderOpen, 
  faPencilSquare, 
  faLineChart, 
  faRandom, 
  faSliders, 
  faCheckCircle, 
  faExclamationCircle, 
  faExclamationTriangle, 
  faInfoCircle, 
  faPlus, 
  faMinus
);

// 全局状态
const textInput = ref('');
const fileInput = ref(null);
const fileDropArea = ref(null);
const waveChart = ref(null);

// 分析结果
const lines = ref([]);
const wordCounts = ref([]);
const displayLines = computed(() => lines.value.slice(0, 20));

// 统计信息
const totalLines = ref(0);
const avgChars = ref('-');
const maxChars = ref('-');
const minChars = ref('-');

// 图表相关
let chart = null;
const chartData = reactive({ 
  labels: [], 
  values: [],
  rawData: [] // 添加原始数据存储
});
const selectedPoint = ref(null);
const chartColor = ref('blue');
const animationType = ref('smooth');
const pointSize = ref(6);  // 点大小初始值
const lineWidth = ref(2);  // 线宽初始值
const chartColors = [
  { name: 'blue', value: '#3B82F6' },
  { name: 'green', value: '#10B981' },
  { name: 'purple', value: '#8B5CF6' },
  { name: 'red', value: '#EF4444' }
];

// 文件处理
const handleDragOver = (e) => {
  e.preventDefault();
  fileDropArea.value.classList.add('border-primary', 'bg-blue-50');
};

const handleDragLeave = () => {
  fileDropArea.value.classList.remove('border-primary', 'bg-blue-50');
};

const handleDrop = (e) => {
  e.preventDefault();
  handleDragLeave();
  const file = e.dataTransfer.files[0];
  if (file) handleFileChange(file);
};

const handleFileClick = () => {
  fileInput.value.click();
};

const handleFileChange = (e) => {
  const file = e.target.files?.[0] || e;
  if (file && isValidFile(file)) {
    const reader = new FileReader();
    reader.onload = (event) => {
      textInput.value = event.target.result;
      analyzeText();
    };
    reader.readAsText(file);
  } else {
    showNotification('请上传 .txt 或 .js 文件', 'error');
  }
};

// 文本分析
const analyzeText = () => {
  const text = textInput.value.trim();
  if (!text) {
    showNotification('请输入文本内容或上传文件', 'warning');
    return;
  }

  lines.value = text.split('\n').filter(line => line.trim() !== '');
  wordCounts.value = lines.value.map(line => line.length);
  console.log('lines:', lines.value, 'wordCounts:', wordCounts.value)
  window.a1 = lines.value;
  window.a2 = wordCounts.value;
  updateStatistics();
  updateChart();
};

// 生成随机文本
const generateRandomText = () => {
  const lineCount = Math.floor(Math.random() * 15) + 5;
  const generatedLines = [];
  for (let i = 0; i < lineCount; i++) {
    const charCount = Math.floor(Math.random() * 50) + 1;
    generatedLines.push(Array(charCount).fill('X').join(''));
  }
  textInput.value = generatedLines.join('\n');
  analyzeText();
};

// 更新统计信息
const updateStatistics = () => {
  const total = wordCounts.value.length;
  if (total === 0) {
    totalLines.value = 0;
    avgChars.value = '-';
    maxChars.value = '-';
    minChars.value = '-';
    return;
  }

  const sum = wordCounts.value.reduce((a, b) => a + b, 0);
  totalLines.value = total;
  avgChars.value = Math.round(sum / total);
  maxChars.value = Math.max(...wordCounts.value);
  minChars.value = Math.min(...wordCounts.value);
};

// 图表初始化
import { nextTick } from 'vue';

// 缩放控制
  const handleZoomOut = () => {
    if (chart) {
      chart.resetZoom();
    }
  };

  const handleZoomIn = () => {
    if (chart) {
      const xAxis = chart.scales.x;
      const currentRange = xAxis.max - xAxis.min;
      const newRange = currentRange * 0.8; // 每次放大20%
      const center = (xAxis.max + xAxis.min) / 2;
      xAxis.min = center - newRange / 2;
      xAxis.max = center + newRange / 2;
      chart.update();
    }
  };
onMounted(() => {
  nextTick(() => {
    const canvas = waveChart.value;
    if (!canvas) {
      showNotification('图表容器未找到', 'error');
      return;
    }

    // 确保canvas已挂载到DOM
    if (!canvas.parentNode) {
      showNotification('图表容器父节点未找到', 'error');
      return;
    }

    const ctx = canvas.getContext('2d');
    if (!ctx) {
      showNotification('图表上下文获取失败', 'error');
      return;
    }

    chart = new Chart(ctx, {
      type: 'line',
      data: {
        labels: [],
        datasets: [{
          label: '字数',
          data: [],
          borderColor: getChartColors(chartColor.value).border,
          backgroundColor: getChartColors(chartColor.value).fill,
          borderWidth: lineWidth.value,  // 初始线宽
          pointRadius: pointSize.value,  // 初始点大小
          pointBackgroundColor: getChartColors(chartColor.value).point,
          pointBorderColor: '#fff',
          pointBorderWidth: 1,
          tension: 0.4,
          fill: true,
          animation: getAnimationConfig()
        }]
      },
      options: {
        onClick: (e) => {
          const points = chart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, false);
          if (points.length) {
            const firstPoint = points[0];
            const dataPoint = chart.data.datasets[0].data[firstPoint.index];
            selectedPoint.value = dataPoint;
          }
        },
        plugins: {
          zoom: {
            zoom: {
              wheel: {
                enabled: true
              },
              mode: 'x'
            }
          }
        }
      }
    });
    generateSampleData();
  });
});

// 组件卸载时销毁Chart实例
onBeforeUnmount(() => {
  if (chart) {
    chart.destroy();
    chart = null;
  }
});

// 更新图表
const updateChart = () => {
  if (!chart) return;
  
  // 确保使用最新数据
  chartData.labels = lines.value.map((_, index) => `行 ${index + 1}`);
  chartData.values = wordCounts.value;

  // 简化数据格式，直接使用数值数组
  const chartDataPoints = wordCounts.value.map((count, index) => ({
    x: index,
    y: count,
    lineNumber: index + 1,
    content: lines.value[index]
  }));

  // 更新图表配置
  chart.data = {
    labels: chartData.labels,
    datasets: [{
      label: '字数',
      data: chartDataPoints,
      borderColor: getChartColors(chartColor.value).border,
      backgroundColor: getChartColors(chartColor.value).fill,
      borderWidth: lineWidth.value,
      pointRadius: pointSize.value,
      pointBackgroundColor: getChartColors(chartColor.value).point,
      pointBorderColor: '#fff',
      pointBorderWidth: 1,
      tension: 0.4,
      fill: true
    }]
  };

  // 强制重绘图表
  chart.update('none'); // 禁用动画立即更新
};

// 颜色切换
const handleColorClick = (color) => {
  chartColor.value = color.name;
  updateChart();
};

// 点大小调节
const handlePointSizeChange = (e) => {
  pointSize.value = Number(e.target.value);  // 确保为数字类型
  updateChart();
};

// 线宽调节
const handleLineWidthChange = (e) => {
  lineWidth.value = Number(e.target.value);  // 确保为数字类型
  updateChart();
};

// 辅助函数
const isValidFile = (file) => {
  const ext = file.name.split('.').pop().toLowerCase();
  return ['txt', 'js'].includes(ext);
};

const getChartColors = (color) => {
  const config = {
    blue: { border: '#3B82F6', fill: 'rgba(59, 130, 246, 0.1)', point: '#3B82F6' },
    green: { border: '#10B981', fill: 'rgba(16, 185, 129, 0.1)', point: '#10B981' },
    purple: { border: '#8B5CF6', fill: 'rgba(139, 92, 246, 0.1)', point: '#8B5CF6' },
    red: { border: '#EF4444', fill: 'rgba(239, 68, 68, 0.1)', point: '#EF4444' }
  };
  return config[color] || config.blue;
};

const getAnimationConfig = () => {
  if (animationType.value === 'wave') {
    return {
      duration: 2000,
      easing: 'linear',
      loop: true,
      generateData: (chart) => {
          if (chart.data.datasets?.[0]?.data) {
            const t = Date.now() / 1000;
            return chart.data.datasets[0].data.map((value, index) => 
              value + Math.sin(index * 0.5 + t) * 5
            );
          }
          return [];
        }
    };
  } else if (animationType.value === 'none') {
    return { duration: 0 };
  }
  return { duration: 1000, easing: 'easeOutQuart' };
};

const generateSampleData = () => {
  const sampleText = `1234a\n123456\n123456789\n123\n1234334\n123232314324324\n1233421343223432`;
  textInput.value = sampleText;
  analyzeText();
};

const showNotification = (message, type = 'info') => {
  const notification = document.createElement('div');
  notification.className = 'notification fixed top-4 right-4 px-6 py-3 rounded-lg shadow-lg z-50 transition-all duration-300 transform translate-x-full';
  
  const iconClass = {
    success: 'fa-check-circle text-green-500',
    error: 'fa-exclamation-circle text-red-500',
    warning: 'fa-exclamation-triangle text-yellow-500',
    info: 'fa-info-circle text-blue-500'
  };

  notification.innerHTML = `
    <div class="flex items-center space-x-3">
      <i class="${iconClass[type] || iconClass.info} text-xl"></i>
      <p>${message}</p>
    </div>
  `;

  switch (type) {
    case 'success':
      notification.classList.add('bg-green-50', 'border-l-4', 'border-green-500', 'text-green-700');
      break;
    case 'error':
      notification.classList.add('bg-red-50', 'border-l-4', 'border-red-500', 'text-red-700');
      break;
    case 'warning':
      notification.classList.add('bg-yellow-50', 'border-l-4', 'border-yellow-500', 'text-yellow-700');
      break;
    default:
      notification.classList.add('bg-blue-50', 'border-l-4', 'border-blue-500', 'text-blue-700');
  }

  document.body.appendChild(notification);
  setTimeout(() => notification.classList.remove('translate-x-full'), 10);
  setTimeout(() => {
    notification.classList.add('translate-x-full');
    setTimeout(() => notification.remove(), 300);
  }, 3000);
};



</script>

<style>
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer utilities {
  .content-auto {
    content-visibility: auto;
  }
  .text-shadow {
    text-shadow: 0 2px 4px rgba(0,0,0,0.1);
  }
  .transition-custom {
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  }
  .wave-animation {
    animation: wave 3s infinite ease-in-out;
  }
  @keyframes wave {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
  }
  .notification-enter {
    transform: translateX(100%);
  }
  .notification-enter-active {
    transform: translateX(0);
    transition: transform 300ms ease-out;
  }
  .notification-exit-active {
    transform: translateX(100%);
    transition: transform 300ms ease-in;
  }
}

.color-option {
  width: 32px;
  height: 32px;
  cursor: pointer;
  transition: transform 0.2s;
}
.color-option:hover {
  transform: scale(1.1);
}
</style>
